import {
  getObject,
  i18n,
  nmAppErrorLog,
  nmAppLog,
  setObject,
} from '@app-nextmesh/common/utils';
import { showLoading } from '@app-nextmesh/components';
import {
  FormField,
  FormNativeSelect,
} from '@app-nextmesh/components/Forms/components';
import {
  isNameEditable,
  isShowType,
} from '@app-nextmesh/components/Forms/components/utils';
import JSONFormatForm from '@app-nextmesh/components/Forms/JSONFormatForm';
import { documentV2 } from '@app-nextmesh/domain';
import { useProjectStore } from '@app-nextmesh/store/project';
import { useSimulationStore } from '@app-nextmesh/store/simulation';
import {
  InputValueType,
  ModelEventType,
  VisualType,
} from '@app-nextmesh/types';
import { events } from '@app-nextmesh/utils';
import { cloneDeep } from 'lodash';
import { useEffect, useRef, useState } from 'react';
import BaseForm from '../BaseForm';
import { IProps } from './types';

interface ISimulationProps extends IProps {
  jsonPath: string; // FormType.FormIndex，比如： condition.Expressions
  name: string; // BoundaryType/Material
  formData: any; // 完整的表单数据
  formType: string; // 变量类型，BodyForce 等
  formFormat: object;
}
export default function SimulationConditionForm({
  jsonPath,
  name,
  formData: initData,
  formType,
  formFormat: initFormFormat,
  onClose,
  onUpdateTitle,
  onUpdate,
}: ISimulationProps) {
  // 需要添加到data中提交到服务器的数据
  const postData = useRef<any>(null);
  // 完整的simulation表单数据，用于提交到服务器
  const [data, setData] = useState<any>(null);
  // 标题
  const [title, setTitle] = useState<string>(null);
  // 具体的formData和formFormat，用于渲染表单界面
  const [formData, setFormData] = useState<any>(null);
  const [formFormat, setFormFormat] = useState<any>(null);
  const resetTitle = useRef({ reset: true, oldTitle: '' });
  const projectInfo = useProjectStore((state) => state.projectInfo);
  const setMaterialSets = useSimulationStore((state) => state.setMaterialSets);
  const setSurfaceInteractionSets = useSimulationStore(
    (state) => state.setSurfaceInteractionSets,
  );
  const setBoundarySets = useSimulationStore((state) => state.setBoundarySets);

  useEffect(() => {
    events.emit(ModelEventType.Loading, VisualType.Geometry);
  }, []);
  useEffect(() => {
    const newData = cloneDeep(initData);
    const mItemsArray = [];
    const surItemsArray = [];

    // 设置材料集，便于其他模块使用
    if (newData.condition) {
      if (newData.condition.materials?.length > 0) {
        newData.condition.materials?.forEach((item, index) => {
          mItemsArray.push({
            name: item.name,
            index,
          });
        });
        setMaterialSets(mItemsArray);
      }
      // 设置接触表面集，便于其他模块使用
      if (newData.condition.contacts?.SurfaceInteraction?.length > 0) {
        newData.condition.contacts.SurfaceInteraction?.forEach(
          (item, index) => {
            surItemsArray.push({
              name: item.name,
              index,
            });
          },
        );
        setSurfaceInteractionSets(surItemsArray);
      }
      setBoundarySets(newData.condition.boundaries ?? []);
    }

    setData(newData);

    setFormFormat(initFormFormat); // 初始化表单格式，此值不会修改

    const item = getObject(newData, jsonPath);

    // 初始化需要提交的值
    const newForm = cloneDeep(item);
    const title = newForm.Name ?? newForm.name ?? name; // .name 逐步替换为 .Name
    setTitle(title);
    resetTitle.current.oldTitle = title;

    setFormData(newForm);
    nmAppLog('SimulationConditionForm:', {
      newData,
      mItemsArray,
      newForm,
      initFormFormat,
    });
    postData.current = cloneDeep(newForm);
    return () => {
      if (resetTitle.current.reset) {
        // 重置标题
        onUpdateTitle?.(resetTitle.current.oldTitle);
      }
    };
  }, [jsonPath, name, initData, formType, initFormFormat]);
  const handleOk = async () => {
    setObject(data, jsonPath, postData.current);

    const hide = showLoading();
    try {
      const newData = await documentV2.updateSimulation(data);
      resetTitle.current.reset = false;
      onUpdate(newData);
      onClose();
    } catch (error) {
      nmAppErrorLog('SimulationConditionForm', 'handleOk', error);
    } finally {
      hide();
    }
  };
  const handleUpdateTitle = (title: string) => {
    postData.current.Name = title;
    setTitle(title);
    onUpdateTitle?.(title);
  };
  const handleClose = () => {
    onClose();
  };
  const handleInputChange = (name: string, value: InputValueType) => {
    setObject(postData.current, name, value);
  };
  if (!formData || !formFormat) {
    return null;
  }
  return (
    <>
      <BaseForm
        disabled={projectInfo.readonly}
        title={title}
        titleEditable={isNameEditable(formFormat)}
        onClose={handleClose}
        onOk={handleOk}
        updateTitle={handleUpdateTitle}>
        {isShowType(formFormat) && (
          <FormField label={i18n.t('BoundaryType')}>
            <FormNativeSelect
              disabled={true}
              value={formType}
              options={[{ value: formType, label: i18n.t(formType) }]}
            />
          </FormField>
        )}
        <JSONFormatForm
          readonly={projectInfo.readonly}
          formData={formData}
          formFormat={formFormat}
          handleInputChange={handleInputChange}
        />
      </BaseForm>
    </>
  );
}
